#ifndef __SV2_SAVER__
#define __SV2_SAVER__

#include "sms_core.h"
#include <string>
#include <chrono>
#include <mutex>
#include <queue>
#include <condition_variable>
#include "sv2_video_saver.h"


namespace sv2
{
  class VideoWriter;

  class ImgMsg {
    public:
      ImgMsg(cv::Mat img_, nlohmann::json msg_) : img(img_), msg(msg_) {}
      cv::Mat img;
      nlohmann::json msg;
  };

  class SaverCppNode_Rknn : public sms::BaseNode
  {
  public:
    SaverCppNode_Rknn(
      std::string job_name,
      std::string param_file,
      std::string ip = "127.0.0.1",
      int port = 9094,
      nlohmann::json kwargs = {}) : 
      sms::BaseNode("SaverCppNode_Rknn", job_name, param_file, ip, port, kwargs)
    {
      this->_det_res_sub = NULL;
      // 读取节点参数
      this->_image_topic = this->get_param("image_topic", "/live/detector/image_results");
      this->_width = this->get_param("width", 1280);
      this->_height = this->get_param("height", 720);
      this->_fps = this->get_param("fps", 25);
      this->_saver_dir = this->get_param("saver_dir", "/home/amov");
      this->params_help();

      /*
      logger.info("image_topic: " + this->_image_topic);
      logger.info("width: " + std::to_string(static_cast<int>(this->_width)));
      logger.info("height: " + std::to_string(static_cast<int>(this->_height)));
      logger.info("fps: " + std::to_string(static_cast<int>(this->_fps)));
      logger.info("saver_dir: " + this->_saver_dir);
      */

      this->_det_res_sub = new sms::Subscriber(this->_image_topic, "std_msgs::Null", std::bind(&SaverCppNode_Rknn::full_res_callback, this, std::placeholders::_1));

      // 默认设置保存路径"/home/amov/Videos"，保存图像尺寸（640，480），帧频25Hz，同步保存检测结果（.svj）
      // this->_vw.setup(this->_saver_dir, cv::Size(this->_width, this->_height), this->_fps, true);
      this->_vw.setup(this->_saver_dir, cv::Size(this->_width, this->_height), this->_fps, true);
    }
    ~SaverCppNode_Rknn()
    {
      if (_det_res_sub != NULL)
        delete _det_res_sub;
    }
    void run();

    void full_res_callback(nlohmann::json msg)
    {
      // 放入到阻塞队列中
      cv::Mat img = sms::sms2cvimg(msg);
      ImgMsg imgmsg(img, msg);
      {
        std::unique_lock<std::mutex> lock(this->_full_queue_mtx);
        this->_full_queue.push(imgmsg);
      }
      // 通知主线程取数据
      this->_full_cv.notify_one();
    }

    int _width;
    int _height;
    int _fps;
    std::string _saver_dir;
    std::string _image_topic;

    VideoWriter _vw;

  private:
    // 订阅话题
    sms::Subscriber* _det_res_sub;

    std::mutex _full_queue_mtx;
    std::queue<ImgMsg> _full_queue;
    std::condition_variable _full_cv;
};

}
#endif
